import fs from 'fs';
import {PageConfig, PagesOptionsPage} from '../types';
import {PathUtil} from "./PathUtil";

/**
 * 页面解析器，用于解析页面文件内容并提取页面配置
 */
export class PageParser {

    /**
     * 解析页面文件中的配置
     * @param filePath 页面文件路径
     * @returns 页面配置对象
     */
    public parsePageOptions(filePath: string): Partial<PagesOptionsPage> | undefined {
        try {
            const content = fs.readFileSync(filePath, 'utf-8');

            // 提取 defineUniPage 中的页面配置
            // 使用更健壮的正则表达式，能够处理嵌套的花括号
            const defineUniPageRegex = /defineUniPage\s*\(\s*(\{(?:[^{}]|(?:\{(?:[^{}]|(?:\{[^{}]*\}))*\}))*\})\s*\)/s;
            const match = content.match(defineUniPageRegex);
            if (!match) return undefined;

            // 从 defineUniPage 中获取配置字符串
            const pageContent = match[1];
            if (!pageContent) return undefined;

            // 使用Function构造函数安全地将字符串转换为对象
            // 这比直接使用JSON.parse更适合处理JavaScript对象字面量
            try {
                // 创建一个函数来返回对象
                const objFunction = new Function(`return ${pageContent}`);
                return {
                    path: PageParser.convertToPagePath(filePath),
                    ...objFunction() as PageConfig
                };
            } catch (evalError) {
                console.error(`解析页面配置对象失败: ${filePath}`, evalError);
                return undefined;
            }
        } catch (error) {
            console.error(`解析页面文件失败: ${filePath}`, error);
            return undefined;
        }
    }

    /**
     * 将页面文件路径转换为 UniApp 页面路径格式
     * @param filePath 页面文件路径，相对于项目根目录
     * @returns UniApp 页面路径
     */
    public static convertToPagePath(filePath: string): string {
        const pagePathWithExt = PathUtil.normalize(filePath).replace(/^src\//, '');
        return pagePathWithExt.replace(/\.\w+$/, '');
    }

    /**
     * 在编译时转换页面文件内容，移除页面配置
     * @param code 原始代码内容
     * @param packageName 引入的包名
     * @returns 转换后的代码，如果没有变更则返回null
     */
    public static transformPageOptions(code: string, packageName: string): string | null {
        try {
            let hasChanged = false;
            let transformedCode = code;

            // 移除 defineUniPage 函数调用，使用更健壮的正则表达式
            const defineUniPageRegex = /defineUniPage\s*\(\s*(\{(?:[^{}]|(?:\{(?:[^{}]|(?:\{[^{}]*\}))*\}))*\})\s*\)/s;
            if (transformedCode.match(defineUniPageRegex)) {
                transformedCode = transformedCode.replace(defineUniPageRegex, '');
                hasChanged = true;
            }

            // 检测并移除 defineUniPage 的引入语句
            // 匹配可能的import语句格式
            const importRegexes = [
                // 匹配 import { defineUniPage } from 'uni-auto-pages'
                new RegExp(`import\\s*{\\s*(?:.*,\\s*)?defineUniPage(?:\\s*,\\s*[^}]*)?\\s*}\\s*from\\s*['"]${packageName}(?:/[^'"]*)?['"]`),
                // 匹配 import defineUniPage from 'uni-auto-pages'
                new RegExp(`import\\s+defineUniPage\\s+from\\s*['"]${packageName}(?:/[^'"]*)?['"]`),
            ];

            for (const regex of importRegexes) {
                const importMatch = transformedCode.match(regex);
                if (importMatch) {
                    if (regex.toString().includes('import\\\\s*{')) {
                        // 处理解构导入的情况
                        const importStatement = importMatch[0];

                        // 如果只导入了defineUniPage，则移除整行
                        if (importStatement.match(/import\s*{\s*defineUniPage\s*}\s*from/)) {
                            transformedCode = transformedCode.replace(importStatement, '');
                        } else {
                            // 如果导入了多个，只移除defineUniPage
                            transformedCode = transformedCode.replace(
                                importStatement,
                                importStatement.replace(/,?\s*defineUniPage\s*,?/, '')
                                    // 修复潜在的语法问题，如 "import { , xxx }" 或 "import { xxx, }"
                                    .replace(/import\s*{\s*,/, 'import {')
                                    .replace(/,\s*}\s*from/, ' } from')
                            );
                        }
                    } else {
                        // 处理默认导入的情况
                        transformedCode = transformedCode.replace(importMatch[0], '');
                    }
                    hasChanged = true;
                }
            }

            return hasChanged ? transformedCode : null;
        } catch (error) {
            console.error('转换页面配置失败:', error);
            return null;
        }
    }
}
